/*
 * $Header: /cvshome/build/org.osgi.service.deploymentadmin/src/org/osgi/service/deploymentadmin/DeploymentPackage.java,v 1.26 2006/07/12 21:22:10 hargrave Exp $
 * 
 * Copyright (c) OSGi Alliance (2005, 2006). All Rights Reserved.
 * 
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package org.osgi.service.deploymentadmin;

import org.osgi.framework.*;

/**
  * The <code>DeploymentPackage</code> object represents a deployment package (already installed
  * or being currently processed). A Deployment Package groups resources as a unit 
  * of management. A deployment package is something that can be installed, updated, 
  * and uninstalled as a unit. A deployment package is a reified concept, like a bundle, 
  * in an OSGi Service Platform. It is not known by the OSGi Framework, but it is managed 
  * by the Deployment Admin service. A deployment package is a stream of resources 
  * (including bundles) which, once processed, will result in new artifacts (effects on 
  * the system) being added to the OSGi platform.  These new artifacts can include 
  * installed Bundles, new configuration objects added to the Configuration Admin service, 
  * new Wire objects added to the Wire Admin service, or changed system properties, etc. All 
  * the changes caused by the processing of a deployment package are persistently 
  * associated with the deployment package, so that they can be appropriately cleaned 
  * up when the deployment package is uninstalled. There is a strict no overlap rule 
  * imposed on deployment packages. Two deployment packages are not allowed to create or 
  * manipulate the same artifact. Obviously, this means that a bundle cannot be in two 
  * different deployment packagess. Any violation of this no overlap rule is considered 
  * an error and the install or update of the offending deployment package must be aborted.<p>
  * 
  * The Deployment Admin service should do as much as possible to ensure transactionality. 
  * It means that if a deployment package installation, update or removal (uninstall) fails 
  * all the side effects caused by the process should be disappeared  and the system 
  * should be in the state in which it was before the process.<p>
  * 
  * If a deployment package is being updated the old version is visible through the 
  * <code>DeploymentPackage</code> interface until the update process ends. After the 
  * package is updated the updated version is visible and the old one is not accessible 
  * any more.
  */
public interface DeploymentPackage {
 
	/**
	 * Gives back the state of the deployment package whether it is stale or not).
     * After uninstall of a deployment package it becomes stale. Any active method calls to a 
     * stale deployment package raise {@link IllegalStateException}.
     * Active methods are the following:<p>
     * 
     * <ul>
     * 		<li>{@link #getBundle(String)}</li>
     * 		<li>{@link #getResourceProcessor(String)}</li>
     * 		<li>{@link #uninstall()}</li>
     * 		<li>{@link #uninstallForced()}</li>
     * </ul>
     * 
	 * @return <code>true</code> if the deployment package is stale. <code>false</code>
	 *         otherwise
     * @see #uninstall
     * @see #uninstallForced
	 */
    boolean isStale();
	  
	/**
	 * Returns the Deployment Pacakage Symbolic Name of the package.
	 * 
	 * @return The name of the deployment package. It cannot be null.
	 */
	String getName();
	  
	/**
	 * Returns the version of the deployment package.
	 * @return version of the deployment package. It cannot be null.
	 */
	Version getVersion();
	  
	/**
	 * Returns an array of {@link BundleInfo} objects representing the bundles specified in the manifest 
	 * of this deployment package. Its size is equal to the number of the bundles in the deployment package. 
	 * 
 	 * @return array of <code>BundleInfo</code> objects 
     * @throws SecurityException if the caller doesn't have the appropriate {@link DeploymentAdminPermission} 
     *         with "metadata" action
	 */
	BundleInfo[] getBundleInfos();  
 
    /**
     * Returns the bundle instance, which is part of this deployment package, that corresponds 
     * to the bundle's symbolic name passed in the <code>symbolicName</code> parameter.
     * This method will return null for request for bundles that are not part 
     * of this deployment package.<p>
     * 
     * As this instance is transient (i.e. a bundle can be removed at any time because of the 
     * dynamic nature of the OSGi platform), this method may also return null if the bundle
     * is part of this deployment package, but is not currently defined to the framework.
     * 
     * @param symbolicName the symbolic name of the requested bundle
     * @return The <code>Bundle</code> instance for a given bundle symbolic name.
     * @throws SecurityException if the caller doesn't have the appropriate {@link DeploymentAdminPermission} 
     *         with "metadata" action
     * @throws IllegalStateException if the package is stale
     */
    Bundle getBundle(String symbolicName);
    
    /**
     * Returns an array of strings representing the resources (including bundles) that 
     * are specified in the  manifest of this deployment package. A string element of the 
     * array is the same as the value of the "Name" attribute in the manifest. The array 
     * contains the bundles as well.<p>
     * 
     * E.g. if the "Name" section of the resource (or individual-section as the 
     * <a href="http://java.sun.com/j2se/1.4.2/docs/guide/jar/jar.html#Manifest%20Specification">Manifest Specification</a> 
     * calls it) in the manifest is the following

     * <pre>
     *     Name: foo/readme.txt
     *     Resource-Processor: foo.rp
     * </pre>
     * 
     * then the corresponding array element is the "foo/readme.txt" string.<p>
     * 
     * @return The string array corresponding to resources. It cannot be null but its 
     *         length can be zero.
     * @throws SecurityException if the caller doesn't have the appropriate {@link DeploymentAdminPermission} 
     *         with "metadata" action
     */
    String[] getResources();   
    
    /**
     * At the time of deployment, resource processor service instances are located to 
     * resources contained in a deployment package.<p> 
     * 
     * This call returns a service reference to the corresponding service instance.
     * If the resource is not part of the deployment package or this call is made during 
     * deployment, prior to the locating of the service to process a given resource, null will 
     * be returned. Services can be updated after a deployment package has been deployed. 
     * In this event, this call will return a reference to the updated service, not to the 
     * instance that was used at deployment time.
     * 
     * @param resource the name of the resource (it is the same as the value of the "Name" 
     *        attribute in the deployment package's manifest) 
     * @return resource processor for the resource or <code>null</cpde>.
     * @throws SecurityException if the caller doesn't have the appropriate {@link DeploymentAdminPermission} 
     *         with "metadata" action
     * @throws IllegalStateException if the package is stale        
     */
    ServiceReference getResourceProcessor(String resource);    

    /**
     * Returns the requested deployment package manifest header from the main section. 
     * Header names are case insensitive. If the header doesn't exist it returns null.<p>
     * 
     * If the header is localized then the localized value is returned (see OSGi Service Platform,
     * Mobile Specification Release 4 - Localization related chapters).
     * 
     * @param header the requested header
     * @return the value of the header or <code>null</code> if the header does not exist
     * @throws SecurityException if the caller doesn't have the appropriate {@link DeploymentAdminPermission} 
     *         with "metadata" action
     */
    String getHeader(String header);

    /**
     * Returns the requested deployment package manifest header from the name 
     * section determined by the resource parameter. Header names are case insensitive. 
     * If the resource or the header doesn't exist it returns null.<p>
     * 
     * If the header is localized then the localized value is returned (see OSGi Service Platform,
     * Mobile Specification Release 4 - Localization related chapters).

     * @param resource the name of the resource (it is the same as the value of the "Name" 
     *        attribute in the deployment package's manifest)
     * @param header the requested header
     * @return the value of the header or <code>null</code> if the resource or the header doesn't exist
     * @throws SecurityException if the caller doesn't have the appropriate {@link DeploymentAdminPermission} 
     *         with "metadata" action
     */
    String getResourceHeader(String resource, String header);
    
	/**
	  * Uninstalls the deployment package. After uninstallation, the deployment package 
	  * object becomes stale. This can be checked by using {@link #isStale()}, 
	  * which will return <code>true</code> when stale.<p>
	  * 
	  * @throws DeploymentException if the deployment package could not be successfully uninstalled. 
	  *         For detailed error code description see {@link DeploymentException}.
	  * @throws SecurityException if the caller doesn't have the appropriate 
	  * 		{@link DeploymentAdminPermission}("&lt;filter&gt;", "uninstall") permission.
	  * @throws IllegalStateException if the package is stale 
	  */
    void uninstall() throws DeploymentException;
 
    /**
     * This method is called to completely uninstall a deployment package, which couldn't be uninstalled
     * using traditional means ({@link #uninstall()}) due to exceptions. After uninstallation, the deployment 
     * package object becomes stale. This can be checked by using {@link #isStale()}, 
     * which will return <code>true</code> when stale.<p>
     *  
     * The method forces removal of the Deployment Package from the repository maintained by the 
     * Deployment Admin service. This method follows the same steps as {@link #uninstall}. However, 
     * any errors or the absence of Resource Processor services are ignored, they must not cause a roll back.
     * These errors should be logged.
     * 
     * @return true if the operation was successful
     * @throws DeploymentException only {@link DeploymentException#CODE_TIMEOUT} and 
     *         {@link DeploymentException#CODE_CANCELLED} can be thrown. For detailed error code description 
	 *         see {@link DeploymentException}.
     * @throws SecurityException if the caller doesn't have the appropriate 
     *         {@link DeploymentAdminPermission}("&lt;filter&gt;", "uninstall_forced") permission.
     * @throws IllegalStateException if the package is stale
     */  
    boolean uninstallForced() throws DeploymentException;  
 
    /**
     * Returns a hash code value for the object.
     * 
     * @return a hash code value for this object
     */
    int hashCode();
  
    /**
     * Indicates whether some other object is "equal to" this one. Two deployment packages 
     * are equal if they have the same deployment package symbolicname and version.
     * 
     * @param other the reference object with which to compare.
     * @return true if this object is the same as the obj argument; false otherwise.
     */
    boolean equals(Object other);
  
}
